# 米粒识别
# In[]
import cv2
import os 
import copy
import numpy as np 

path = os.path.abspath('第二次作业/Rice.jpg')
riceImg = cv2.imread(path)

gray = cv2.cvtColor(riceImg,cv2.COLOR_BGR2GRAY)
# 大津算法
_,bw = cv2.threshold(gray,0,0xff,cv2.THRESH_OTSU)
# 开运算消除噪声
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
# 开运算
bw = cv2.morphologyEx(bw,cv2.MORPH_OPEN,element)

seg = copy.deepcopy(bw)
# 得到轮廓集合
bin,cnts,hier = cv2.findContours(seg,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
count = 0
areaData = []
riceLenth = []
for i in range(len(cnts),0,-1):
    c = cnts[i-1]
    area = cv2.contourArea(c)
    if area < 10:
        continue
    count += 1
    areaData.append(area)

    _,(lenth1,lenth2),_ = cv2.minAreaRect(c)
    lenth = max(lenth1,lenth2)
    riceLenth.append(lenth)
    print('blob',i,' 面积: ',area,' 长度： ',lenth)
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(riceImg,(x,y),(x+w,y+h),(0,0,0xff),1)
    cv2.putText(riceImg,str(count),(x,y),cv2.FONT_HERSHEY_PLAIN,0.5,(0,0xff,0))

print('米粒数量：',count)
cv2.imshow("rice",riceImg)
cv2.imshow("阈值化图",bw)

areaData = np.array(areaData)
var = areaData.var(0)
mean = areaData.mean(0)
var_std = areaData.std(0)
print('面积数据：',var,mean,var_std)
std_data = areaData[(areaData > mean-1.5*var_std) & (areaData < mean + 1.5 * var_std)] 
print('面积在3标准差内的米粒数量为：',len(std_data))

riceLenth = np.array(riceLenth)
var = riceLenth.var(0)
mean = riceLenth.mean(0)
var_std = riceLenth.std(0)
std_data = riceLenth[(riceLenth > mean - 1.5 * var_std) & (riceLenth < mean + 1.5 * var_std)]
print('长度数据：',var,mean,var_std)
print('长度在3标准差内的米粒数为：',len(std_data))

cv2.waitKey()
cv2.destroyAllWindows()